/**
 * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 */

package com.iwindplus.im.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.github.yulichang.repository.JoinCrudRepository;
import com.iwindplus.boot.domain.vo.FilePathVO;
import com.iwindplus.im.domain.dto.ChatGroupUserDTO;
import com.iwindplus.im.domain.dto.ChatGroupUserSaveDTO;
import com.iwindplus.im.domain.dto.ChatGroupUserSearchDTO;
import com.iwindplus.im.domain.vo.ChatGroupUserPageVO;
import com.iwindplus.im.domain.vo.ChatGroupUserVO;
import com.iwindplus.im.server.mapper.ChatGroupUserMapper;
import com.iwindplus.im.server.model.ChatGroupUserDO;
import com.iwindplus.im.server.service.ChatGroupUserService;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 聊天群用户业务层接口实现类.
 *
 * @author zengdegui
 * @since 2020/3/25
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class ChatGroupUserServiceImpl extends JoinCrudRepository<ChatGroupUserMapper, ChatGroupUserDO> implements ChatGroupUserService {

    @Override
    public boolean save(ChatGroupUserSaveDTO entity) {
        Long orgId = entity.getOrgId();
        entity.setOrgId(orgId);
        entity.setSeq(this.getNextSeq(entity.getChatGroupId()));
        final ChatGroupUserDO model = BeanUtil.copyProperties(entity, ChatGroupUserDO.class);
        super.save(model);
        entity.setId(model.getId());
        return Boolean.TRUE;
    }

    @Override
    public boolean saveBatch(List<ChatGroupUserSaveDTO> entities) {
        AtomicReference<Integer> seq = new AtomicReference<>();
        AtomicBoolean flag = new AtomicBoolean(true);
        List<ChatGroupUserDTO> saveList = new ArrayList<>(10);
        entities.forEach(entity -> {
            // 判断群用户是否重复
            LambdaQueryWrapper<ChatGroupUserDO> queryWrapper = Wrappers.lambdaQuery(ChatGroupUserDO.class)
                .eq(ChatGroupUserDO::getChatGroupId, entity.getChatGroupId())
                .eq(ChatGroupUserDO::getUserId, entity.getUserId());
            final ChatGroupUserDO data = super.getOne(queryWrapper);
            if (Objects.isNull(data)) {
                if (flag.get()) {
                    seq.set(this.getNextSeq(entity.getChatGroupId()));
                    flag.set(false);
                }
                entity.setSeq(seq.getAndSet(seq.get() + 1));
                saveList.add(entity);
            }
        });
        if (CollUtil.isNotEmpty(saveList)) {
            final List<ChatGroupUserDO> doList = BeanUtil.copyToList(saveList, ChatGroupUserDO.class);
            super.saveBatch(doList, DEFAULT_BATCH_SIZE);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean removeChatGroupByIds(List<Long> ids) {
        return CollUtil.isNotEmpty(ids) && SqlHelper.retBool(super.baseMapper.deleteByIds(ids));
    }

    @Override
    public boolean removeByChatGroupIds(List<Long> chatGroupIds) {
        return CollUtil.isNotEmpty(chatGroupIds) && SqlHelper.retBool(super.baseMapper.deleteByChatGroupIds(chatGroupIds));
    }

    @Override
    public IPage<ChatGroupUserPageVO> page(PageDTO<ChatGroupUserDO> page, ChatGroupUserSearchDTO entity) {
        page.setOptimizeCountSql(Boolean.FALSE);
        page.setOptimizeJoinOfCountSql(Boolean.FALSE);
        final IPage<ChatGroupUserPageVO> modelPage = super.baseMapper.selectPageByCondition(page, entity);
        return modelPage;
    }

    /**
     * 查询下一个排序号.
     *
     * @param chatGroupId 聊天群主键
     * @return Integer
     */
    private Integer getNextSeq(Long chatGroupId) {
        QueryWrapper<ChatGroupUserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ChatGroupUserDO::getChatGroupId, chatGroupId);
        queryWrapper.select("max(seq) as seq");
        Function<Object, Integer> function = val -> Integer.valueOf(val.toString());
        Integer data = super.getObj(queryWrapper, function);
        return Optional.ofNullable(data).map(x -> x + 1).orElse(1);
    }

    private void buildUserInfo(ChatGroupUserVO data, List<FilePathVO> filePaths) {
        if (CollUtil.isEmpty(filePaths)) {
            return;
        }
        filePaths.forEach(p -> {
            if (CharSequenceUtil.isNotBlank(data.getUserAvatar()) && data.getUserAvatar().equals(p.getRelativePath())) {
                data.setUserAvatar(p.getAbsolutePath());
            }
        });
    }
}
